import json
import logging
from django.http import JsonResponse
from django.utils.deprecation import MiddlewareMixin

logger = logging.getLogger('django')

class RequestResponseLoggingMiddleware(MiddlewareMixin):
    """
    中间件：记录请求和响应的详细信息，便于调试
    """
    
    def process_request(self, request):
        """处理请求前记录请求信息"""
        request_path = request.path
        request_method = request.method
        request_content_type = request.headers.get('Content-Type', '')
        request_origin = request.headers.get('Origin', '')
        
        # 记录请求基本信息
        logger.debug(f"请求开始: {request_method} {request_path}")
        logger.debug(f"请求头: Content-Type={request_content_type}, Origin={request_origin}")
        
        # 尝试记录请求体
        if request.body:
            try:
                body_data = json.loads(request.body)
                # 隐藏敏感信息如密码
                if 'password' in body_data:
                    body_data['password'] = '******'
                logger.debug(f"请求体: {body_data}")
            except:
                logger.debug(f"请求体: (无法解析为JSON)")
        
        # 允许CORS预检请求直接通过
        if request_method == 'OPTIONS':
            response = JsonResponse({})
            response["Access-Control-Allow-Origin"] = "*"
            response["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
            response["Access-Control-Allow-Headers"] = "Content-Type, Authorization, X-Requested-With, Accept, X-CSRFToken"
            response["Access-Control-Max-Age"] = "86400"
            return response
        
        return None
    
    def process_response(self, request, response):
        """处理响应前添加CORS头并记录响应信息"""
        # 添加CORS头到所有响应
        response["Access-Control-Allow-Origin"] = "*"
        response["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
        response["Access-Control-Allow-Headers"] = "Content-Type, Authorization, X-Requested-With, Accept, X-CSRFToken"
        
        # 记录响应信息
        status_code = getattr(response, 'status_code', None)
        logger.debug(f"响应结束: 状态码={status_code}")
        
        try:
            if hasattr(response, 'content'):
                if len(response.content) < 500:  # 避免记录过大的响应
                    logger.debug(f"响应内容: {response.content.decode('utf-8')}")
                else:
                    logger.debug(f"响应内容: (内容过大，已截断) {response.content[:200].decode('utf-8')}...")
        except:
            logger.debug("响应内容: (无法解码)")
        
        return response


class ExceptionHandlingMiddleware(MiddlewareMixin):
    """
    中间件：处理未捕获的异常，返回友好的错误信息
    """
    
    def process_exception(self, request, exception):
        """处理视图函数中的异常"""
        logger.error(f"未捕获异常: {str(exception)}")
        logger.error(f"异常类型: {type(exception).__name__}")
        
        import traceback
        logger.error(f"异常堆栈: {traceback.format_exc()}")
        
        response = JsonResponse({
            'status': 'error',
            'message': '服务器内部错误，请稍后再试',
            'detail': str(exception)
        }, status=500)
        
        # 添加CORS头
        response["Access-Control-Allow-Origin"] = "*"
        response["Access-Control-Allow-Methods"] = "GET, POST, PUT, DELETE, OPTIONS"
        response["Access-Control-Allow-Headers"] = "Content-Type, Authorization, X-Requested-With, Accept"
        
        return response


class UniAppCompatibilityMiddleware(MiddlewareMixin):
    """
    中间件：专门处理uni-app请求格式兼容
    """
    
    def process_request(self, request):
        """处理uni-app特殊请求格式"""
        # 检查Content-Type
        content_type = request.headers.get('Content-Type', '')
        if 'application/json' in content_type and request.body:
            try:
                # 解析JSON请求体
                body_data = json.loads(request.body)
                # 如果是uni-app格式的请求，进行转换
                if isinstance(body_data, dict):
                    # 已经是字典格式，不需要处理
                    pass
                # 处理uni-app可能的其他格式
                else:
                    logger.debug(f"转换非标准请求格式: {body_data}")
                    # 可以在这里添加特殊格式转换
            except json.JSONDecodeError:
                logger.warning(f"无法解析JSON请求体: {request.body}")
        
        return None 